﻿using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media.Imaging;
using System.Drawing;
using System.Drawing.Imaging;
using System.Windows;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Runtime.InteropServices;



namespace CSharp_Remote_Control.Utils
{
    internal class ScreenUtil
    {

        [DllImport("user32.dll")]
        private static extern IntPtr GetDesktopWindow();

        [DllImport("user32.dll")]
        private static extern IntPtr GetWindowDC(IntPtr hWnd);

        [DllImport("gdi32.dll")]
        private static extern IntPtr CreateCompatibleBitmap(IntPtr hdc, int nWidth, int nHeight);

        [DllImport("gdi32.dll")]
        private static extern IntPtr CreateCompatibleDC(IntPtr hdc);

        [DllImport("gdi32.dll")]
        private static extern IntPtr SelectObject(IntPtr hdc, IntPtr hObject);

        [DllImport("gdi32.dll")]
        private static extern bool BitBlt(IntPtr hdcDest, int xDest, int yDest, int wDest, int hDest, IntPtr hdcSrc, int xSrc, int ySrc, int rop);

        [DllImport("gdi32.dll")]
        private static extern bool DeleteDC(IntPtr hdc);

        [DllImport("gdi32.dll")]
        private static extern bool DeleteObject(IntPtr hObject);

        [DllImport("user32.dll")]
        private static extern bool ReleaseDC(IntPtr hWnd, IntPtr hDc);

        public static Bitmap CaptureScreenC()
        {
            IntPtr hWnd = GetDesktopWindow();
            IntPtr hdcSrc = GetWindowDC(hWnd);
            IntPtr hdcDest = CreateCompatibleDC(hdcSrc);

            Rectangle bounds = Screen.PrimaryScreen.Bounds;
            IntPtr hBitmap = CreateCompatibleBitmap(hdcSrc, bounds.Width, bounds.Height);
            IntPtr hOld = SelectObject(hdcDest, hBitmap);

            //TODO: 多线程同时截屏然后合并
            BitBlt(hdcDest, 0, 0, bounds.Width, bounds.Height, hdcSrc, 0, 0, 0x00CC0020); // SRCCOPY

            Bitmap bitmap = Image.FromHbitmap(hBitmap);

            SelectObject(hdcDest, hOld);
            DeleteDC(hdcDest);
            ReleaseDC(hWnd, hdcSrc);
            DeleteObject(hBitmap);

            return bitmap;
        }





        public static Bitmap CaptureScreen()
        {
            //Task task1 = new Task(() => { });
            //Task task2 = new Task(() => { });
            Rectangle bounds = Screen.PrimaryScreen.Bounds;
            Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);

            using (Graphics g = Graphics.FromImage(bitmap))
            {
                g.CopyFromScreen(bounds.Location, System.Drawing.Point.Empty, new System.Drawing.Size(
                    bounds.Size.Width / 2,
                    bounds.Size.Height
                ));
            }

            return bitmap;
        }


        /// <summary>
        /// Graphics 需要手动释放
        /// </summary>
        /// <param name="g"></param>
        /// <returns></returns>
        public static Bitmap CaptureScreen(Graphics g)
        {
            //Task task1 = new Task(() => { });
            //Task task2 = new Task(() => { });
            Rectangle bounds = Screen.PrimaryScreen.Bounds;
            Bitmap bitmap = new Bitmap(bounds.Width, bounds.Height);

            g.CopyFromScreen(bounds.Location, System.Drawing.Point.Empty, new System.Drawing.Size(
                bounds.Size.Width / 2,
                bounds.Size.Height
            ));

            return bitmap;
        }

        public static async Task<Bitmap> CaptureScreenAsync()
        {
            Bitmap bitmap1 = new Bitmap(1, 1);
            Bitmap bitmap2 = new Bitmap(1, 1);
            Rectangle bounds = Screen.PrimaryScreen.Bounds;
            Task task1 = Task.Run(() =>
            {
                bitmap1 = new Bitmap(bounds.Width / 2, bounds.Height);

                using (Graphics g = Graphics.FromImage(bitmap1))
                {
                    g.CopyFromScreen(
                        bounds.Location
                        , System.Drawing.Point.Empty
                        , new System.Drawing.Size(bounds.Size.Width / 2, bounds.Size.Height)
                        );
                }
            });
            Task task2 = Task.Run(() =>
            {
                bitmap2 = new Bitmap(bounds.Width / 2, bounds.Height);

                using (Graphics g = Graphics.FromImage(bitmap2))
                {
                    g.CopyFromScreen(
                        new System.Drawing.Point(bitmap2.Width, 0) // 右边一般
                        , System.Drawing.Point.Empty
                        , new System.Drawing.Size(bounds.Size.Width / 2, bounds.Size.Height)
                        );
                }
            });

            Task.WaitAll(new Task[] { task1, task2 });

            return MergeBitmaps(bitmap1, bitmap2);
        }


        static Bitmap MergeBitmaps(Bitmap bitmap1, Bitmap bitmap2)
        {
            // 创建一个新的 Bitmap，大小足够容纳两个图像
            int width = Math.Max(bitmap1.Width, bitmap2.Width);
            int height = bitmap1.Height;

            Bitmap mergedBitmap = new Bitmap(width, height);

            using (Graphics g = Graphics.FromImage(mergedBitmap))
            {
                // 清空背景为透明 (也可以选择其他颜色)
                g.Clear(System.Drawing.Color.Transparent);

                // 绘制第一个图像 (bitmap1)
                g.DrawImage(bitmap1, new System.Drawing.Point(0, 0));

                // 绘制第二个图像 (bitmap2)，可以指定位置
                g.DrawImage(bitmap2, new System.Drawing.Point(bitmap1.Width, bitmap1.Height));  // 将第二个图像放在第一个图像右方
            }

            bitmap1.Dispose();
            bitmap2.Dispose();

            return mergedBitmap;
        }


        public static BitmapSource ConvertBitmapToBitmapSource(Bitmap bitmap)
        {
            using (MemoryStream memory = new MemoryStream())
            {
                bitmap.Save(memory, ImageFormat.Png);
                memory.Position = 0;
                BitmapImage bitmapImage = new BitmapImage();
                bitmapImage.BeginInit();
                bitmapImage.StreamSource = memory;
                bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
                bitmapImage.EndInit();
                return bitmapImage;
            }
        }






    }
}
